package com.defangit.award.orm;

import com.defangit.award.domain.WinningInfo;
import com.defangit.award.domain.WinningStatus;
import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.hibernate.event.spi.*;
import org.hibernate.persister.entity.EntityPersister;

import java.util.Arrays;
import java.util.EnumSet;

/**
 * Created by zhangfagen on 2019/1/10.
 */
public class PrizeUsedHandler implements PostCommitInsertEventListener,PostCommitUpdateEventListener {
    @Override
    public void onPostInsert(PostInsertEvent event) {
        if(event.getEntity() instanceof WinningInfo){
            updatePrizeUsed((WinningInfo)event.getEntity());
        }
    }

    /**
     * Called when a commit fails and an an entity was scheduled for insertion
     *
     * @param event the insert event to be handled
     */
    @Override
    public void onPostInsertCommitFailed(PostInsertEvent event) {

    }

    /**
     * Does this listener require that after transaction hooks be registered?   Typically this is {@code true}
     * for post-insert event listeners, but may not be, for example, in JPA cases where there are no callbacks defined
     * for the particular entity.
     *
     * @param persister The persister for the entity in question.
     * @return {@code true} if after transaction callbacks should be added.
     */
    @Override
    public boolean requiresPostCommitHanding(EntityPersister persister) {
        return true;
    }

    @Override
    public void onPostUpdate(PostUpdateEvent event) {
        if(event.getEntity() instanceof WinningInfo)
            updatePrizeUsed((WinningInfo) event.getEntity());
    }

    private void updatePrizeUsed(WinningInfo info){
        if(info.getStatus()== WinningStatus.WINED && info.getPrize()!=null){
            int prize=info.getPrize().getId();
            String hql="update Prize p set p.prizeUsed=(select count(w.id) from WinningInfo w where w.prize.id=:prize and w.status in :status) where p.id=:prize";
//            Session session1=HibernateUtil.INSTANCE.getSession();
//            session1.evict(info.getPrize());
            StatelessSession session=HibernateUtil.INSTANCE.getSessionFactory().openStatelessSession();
            session.beginTransaction();
            session.createQuery(hql)
                    .setParameter("prize",prize)
                    .setParameterList("status", Arrays.asList(WinningStatus.WINED,WinningStatus.CASHED))
                    .executeUpdate();
            session.getTransaction().commit();
        }
    }

    /**
     * Called when a commit fails and an an entity was scheduled for update
     *
     * @param event the update event to be handled
     */
    @Override
    public void onPostUpdateCommitFailed(PostUpdateEvent event) {
        if(event.getEntity() instanceof WinningInfo)
            updatePrizeUsed((WinningInfo) event.getEntity());
    }

}
